home *** CD-ROM | disk | FTP | other *** search
/ Ham Radio 2000 #1 / Ham Radio 2000.iso / ham2000 / misc / worldmap / mapvu20 / mapgraph.pas < prev    next >
Encoding:
Pascal/Delphi Source File  |  1989-01-11  |  22.6 KB  |  610 lines

  1. Unit mapgraph; { low level graphics routines for MAPVIEW.PAS                 }
  2.  
  3. { Copyright A.J. van den Bogert and Gisbert W.Selke Dec 1988                 }
  4.  
  5. {$UNDEF  DEBUG }                    { DEFINE while debugging }
  6.  
  7. {$IFDEF DEBUG }
  8. {$A+,R+,S+,I+,D+,F-,V-,B-,L+ }
  9. {$ELSE }
  10. {$A+,R-,S-,I+,D-,F-,V-,B-,L+ }
  11. {$ENDIF }
  12. {$M 65520,0,560000 }
  13.  
  14. {$IFDEF CPU87 }
  15. {$N+ }
  16. {$ELSE }
  17. {$N- }
  18. {$ENDIF }
  19.  
  20. Interface
  21.  
  22. Uses Dos, Crt, Graph;
  23.  
  24. {$IFOPT N+ }
  25. Type real = single;
  26. {$ENDIF }
  27.  
  28. Const currversion = 2;                  { current version of file format }
  29.       uparr  = #72;                     { code of up arrow }
  30.       dnarr  = #80;                     { code of down arrow }
  31.       lfarr  = #75;                     { code of left arrow }
  32.       rtarr  = #77;                     { code of right arrow }
  33.       cuparr = #141;                    { maybe code of control-up arrow }
  34.       cdnarr = #145;                    { maybe code of control-down arrow }
  35.       clfarr = #115;                    { code of control-left arrow }
  36.       crtarr = #116;                    { code of control-right arrow }
  37.       ctrlc  = #3;                      { code of control-c }
  38.       esc    = #27;                     { code of escape }
  39.       cr     = #13;                     { code of carriage return }
  40.       bksp   = #8;                      { code of backspace }
  41.  
  42. Type scrfile = file;                    { screen save file type }
  43.      picdesc = Record                   { screen file header record }
  44.                  version, follow : byte;
  45.                  grdriver, grmode : integer;
  46.                  size : word;
  47.                  xmin, ymin : integer;
  48.                End;
  49.      scrsav  = Record                   { screen save record }
  50.                  size : word;
  51.                  vptr : pointer;
  52.                End;
  53.  
  54. Var xmaxpix, ymaxpix : integer;         { minimum and maximum coordinates }
  55.     aspect : real;                      { aspect ratio of x and y pixels }
  56.     colourglb, maxcolour : word;        { current colour, maximum colour }
  57.     thisgraphdriver, thisgraphmode : integer; { current graphics mode }
  58.  
  59. Procedure initgraphic;                  { prepare graphics }
  60. Procedure leavegraphic;                 { shut down graphics }
  61. Procedure newgraphmode(grm : integer);  { set non-standard graphics mode }
  62. Procedure logo(title,subtitle:string);  { show logo }
  63. Procedure erasescreen;                  { erase entire graphics screen }
  64. Procedure preservescreen;               { save screen for later re-use }
  65. Procedure restorescreen;                { restore previously saved screen }
  66. Procedure hline(iy: integer);           { draw a horizontal full length line }
  67. Procedure vline(ix: integer);           { draw a vertical full length line }
  68. Procedure dotline(x1, y1, x2, y2 : integer; Var dotflag : boolean);
  69.                                         { draw a dotted line }
  70. Procedure unprompt;                     { remove prompt made by prompt }
  71. Procedure prompt(t : string);           { display a prompt }
  72. Function  confirmquit(t:string):boolean;{ confirm something }
  73. Function  checkuser : boolean;          { check for user interaction }
  74. Procedure showmsg(t : string);          { show informative message }
  75. Procedure errmsg(t : string);           { show error message }
  76. Procedure showprogress(what : byte);    { show a sign of progress top right }
  77. Procedure save(Var screenfile:scrfile); { save complete screen to file }
  78. Procedure scrprint(prno, nrep : byte);  { print screen on Epson-type printer }
  79. Function  intext(Var t : string; maxlg : byte) : boolean;
  80.                   { read a string of given max length during graphics mode; }
  81.                   { return True if no special key was hit }
  82.  
  83. Implementation
  84.  
  85. Const maxchunk = 10;       { maximum number of chunks of a screen }
  86.  
  87. Type scrpak = Record
  88.                 size : word;
  89.                 xmin, xmax : integer;
  90.                 vptr : pointer;
  91.               End;
  92.  
  93. Var savrec : scrsav;
  94.     psc : Array [1..maxchunk] Of scrpak;
  95.     nchunk : byte;
  96.     tw, th, ltrsiz, hlinsiz, vlinsiz : word;
  97.     isput : boolean;
  98.     hlinpic, vlinpic, curspic, nilpic, smilepic : pointer;
  99.  
  100. Procedure initgraphic;
  101. { prepare for graphics, clear screen                                         }
  102.   Var grerrcode, axmax, savxmax : integer;
  103.       xasp, yasp, isiz : word;
  104.  
  105.   Procedure initpics;
  106.   { initialize image buffers for lines and graphics text input cursor        }
  107.   Begin                                                           { initpics }
  108.     Line(0,0,xmaxpix,0);
  109.     hlinsiz := ImageSize(0,0,xmaxpix,1); { some bug in TP 4.0 requires }
  110.     GetMem(hlinpic,hlinsiz);             { height > 1                  }
  111.     If hlinpic <> Nil Then GetImage(0,0,xmaxpix,1,hlinpic^);
  112.     Line(0,0,0,ymaxpix);
  113.     vlinsiz := ImageSize(0,0,0,ymaxpix); { width = 1 seems OK, though }
  114.     GetMem(vlinpic,vlinsiz);
  115.     If vlinpic <> Nil Then GetImage(0,0,0,ymaxpix,vlinpic^);
  116.     ClearDevice;
  117.     tw := TextWidth('M');
  118.     th := TextHeight('Ap');
  119.     ltrsiz := ImageSize(0,0,tw,th);
  120.     GetMem(curspic,ltrsiz);
  121.     GetMem(nilpic,ltrsiz);
  122.     GetMem(smilepic,ltrsiz);
  123.     If nilpic <> Nil Then GetImage(0,0,tw,th,nilpic^);
  124.     SetFillStyle(CloseDotFill,GetMaxColor);
  125.     Bar(0,0,tw,th);
  126.     If curspic <> Nil Then GetImage(0,0,tw,th,curspic^);
  127.     ClearDevice;
  128.     outtextxy(0,0,#2);
  129.     If smilepic <> Nil Then GetImage(0,0,tw,th,smilepic^);
  130.     ClearDevice;
  131.   End;                                                            { initpics }
  132.  
  133.   Procedure memerror;
  134.   { notify user that memory is not sufficient to preserve pictures           }
  135.     Var ch : char;
  136.   Begin                                                           { memerror }
  137.     RestoreCRTMode;
  138.     writeln('Your system has not enough free memory for preserving MapView ',
  139.             'pictures.');
  140.     writeln('Hence, pictures will be erased on certain commands.');
  141.     writeln('Try to remove some resident programmes you have loaded,');
  142.     writeln('or switch to a lower resolution graphics mode before the ',
  143.             'next run.');
  144.     ch := ReadKey;
  145.     SetGraphMode(thisgraphmode);
  146.     axmax := xmaxpix;
  147.   End;                                                            { memerror }
  148.  
  149. Begin                                                          { initgraphic }
  150.   thisgraphdriver := Detect;
  151.   initgraph(thisgraphdriver,thisgraphmode,'');
  152.   grerrcode := GraphResult;
  153.   If grerrcode <> 0 Then
  154.   Begin
  155.     writeln('Graphics error:',GraphErrorMsg(grerrcode));
  156.     Halt(1);
  157.   End;
  158.   SetTextStyle(DefaultFont,HorizDir,1);
  159.   ClearDevice;
  160.   xmaxpix := GetMaxX;
  161.   ymaxpix := GetMaxY;
  162.   GetAspectRatio(xasp,yasp);
  163.   aspect := yasp / xasp;
  164.   maxcolour := GetMaxColor;
  165.   colourglb := maxcolour; { start plotting WHITE }
  166.   SetColor(colourglb);
  167.   initpics;
  168.   savrec.vptr := Nil;
  169.   nchunk := 0;
  170.   Repeat
  171.     Inc(nchunk);
  172.     isiz := ImageSize(0,0,xmaxpix Div nchunk,ymaxpix);
  173.   Until (isiz > 0) And (isiz <= 65521);
  174.   savxmax := xmaxpix Div nchunk;
  175.   axmax := -1;
  176.   nchunk := 0;
  177.   Repeat
  178.     Inc(nchunk);
  179.     With psc[nchunk] Do
  180.     Begin
  181.       xmin := Succ(axmax);
  182.       axmax := xmin + savxmax;
  183.       If axmax > xmaxpix Then axmax := xmaxpix;
  184.       xmax := axmax;
  185.       size := ImageSize(xmin,0,xmax,ymaxpix);
  186.       GetMem(vptr,size);
  187.       If vptr = Nil Then memerror;
  188.     End;
  189.   Until axmax >= xmaxpix;
  190. End;                                                           { initgraphic }
  191.  
  192. Procedure newgraphmode(grm : integer);
  193. { set different graphics mode, if admissible; otherwise set highest          }
  194. { graphics mode possible                                                     }
  195.   Var lomode, himode : integer;
  196. Begin                                                         { newgraphmode }
  197.   GetModeRange(thisgraphdriver,lomode,himode);
  198.   If grm < lomode Then grm := lomode;
  199.   If grm < himode Then grm := himode;
  200.   SetGraphMode(grm);
  201.   thisgraphmode := grm;
  202. End;                                                          { newgraphmode }
  203.  
  204. Procedure leavegraphic;
  205. { shut down graphics, clear screen                                           }
  206.   Var i : byte;
  207. Begin                                                         { leavegraphic }
  208.   CloseGraph;
  209.   If hlinpic  <> Nil Then FreeMem(hlinpic,hlinsiz);
  210.   If vlinpic  <> Nil Then FreeMem(vlinpic,vlinsiz);
  211.   If curspic  <> Nil Then FreeMem(curspic,ltrsiz);
  212.   If nilpic   <> Nil Then FreeMem(nilpic,ltrsiz);
  213.   If smilepic <> Nil Then FreeMem(smilepic,ltrsiz);
  214.   For i := 1 To nchunk Do FreeMem(psc[i].vptr,psc[i].size);
  215.   thisgraphdriver := -1;
  216.   thisgraphmode   := -1;
  217. End;                                                          { leavegraphic }
  218.  
  219. Procedure logo(title, subtitle : string);
  220. { display logo                                                               }
  221. Begin                                                                 { logo }
  222.   SetTextStyle(DefaultFont,HorizDir,7);
  223.   OutTextXY((xmaxpix-TextWidth(title)) Div 2,ymaxpix Div 3,title);
  224.   SetTextStyle(DefaultFont,HorizDir,1);
  225.   OutTextXY((xmaxpix-TextWidth(subtitle)) Div 2,(2*ymaxpix) Div 3,subtitle);
  226. End;                                                                  { logo }
  227.  
  228. Procedure erasescreen;
  229. { blank screen                                                               }
  230. Begin                                                          { erasescreen }
  231.   SetViewPort(0,0,xmaxpix,ymaxpix,True);
  232.   ClearViewPort;
  233. End;                                                           { erasescreen }
  234.  
  235. Procedure preservescreen;
  236. { preserve current graphics screen for later restore                         }
  237.   Var i : byte;
  238. Begin                                                       { preservescreen }
  239.   SetViewPort(0,0,xmaxpix,ymaxpix,True);
  240.   For i := 1 To nchunk Do With psc[i] Do
  241.       If vptr <> Nil Then GetImage(xmin,0,xmax,ymaxpix,vptr^);
  242. End;                                                        { preservescreen }
  243.  
  244. Procedure restorescreen;
  245. { restore graphics screen previously saved                                   }
  246.   Var i : byte;
  247. Begin                                                        { restorescreen }
  248.   SetGraphMode(GetGraphMode);
  249.   SetViewPort(0,0,xmaxpix,ymaxpix,True);
  250.   For i := 1 To nchunk Do With psc[i] Do
  251.            If vptr <> Nil Then PutImage(xmin,0,vptr^,NormalPut);
  252. End;                                                         { restorescreen }
  253.  
  254. Procedure hline(iy: integer);
  255. { put full-width horizontal line on screen                                   }
  256. Begin                                                                { hline }
  257.   PutImage(0,iy,hlinpic^,XOrPut);
  258. End;                                                                 { hline }
  259.  
  260. Procedure vline(ix: integer);
  261. { put full-height vertical line on screen                                    }
  262. Begin                                                                { vline }
  263.   PutImage(ix,0,vlinpic^,XOrPut);
  264. End;                                                                 { vline }
  265.  
  266. Procedure dotline(x1, y1, x2, y2 : integer; Var dotflag : boolean);
  267. { draw a dotted line seamlessly extending a previous dotted one              }
  268.   Var deltax, deltay, xstep, ystep, direction : integer;
  269. Begin                                                              { dotline }
  270.   If x1 <= x2 Then xstep := 1 Else xstep := -1;
  271.   If y1 <= y2 Then ystep := 1 Else ystep := -1;
  272.   deltax := Abs(x2 - x1);
  273.   deltay := Abs(y2 - y1);
  274.   If deltax = 0 Then direction := -1 Else direction := 0;
  275.   While Not ((x1 = x2) and (y1 = y2)) Do
  276.   Begin
  277.     If dotflag Then PutPixel(x1,y1,colourglb);
  278.     dotflag := Not dotflag;
  279.     If direction < 0 Then
  280.     Begin
  281.       y1 := y1 + ystep;
  282.       direction := direction + deltax;
  283.     End
  284.     Else
  285.     Begin
  286.       x1 := x1 + xstep;
  287.       direction := direction - deltay;
  288.     End;
  289.   End;
  290. End;                                                               { dotline }
  291.  
  292. Procedure unprompt;
  293. { remove prompt from screen                                                  }
  294. Begin                                                             { unprompt }
  295.   With savrec Do
  296.   Begin
  297.     If vptr <> Nil Then
  298.     Begin
  299.       SetViewPort(0,0,xmaxpix,ymaxpix,True);
  300.       PutImage(0,0,vptr^,NormalPut);
  301.       FreeMem(vptr,size);
  302.     End;
  303.     vptr := Nil;
  304.   End;
  305. End;                                                              { unprompt }
  306.  
  307. Procedure prompt(t : string);
  308. { prompt user on graphics screen                                             }
  309.   Var ht, lg : word;
  310. Begin                                                               { prompt }
  311.   unprompt;
  312.   With savrec Do
  313.   Begin
  314.     ht := TextHeight(t);  lg := TextWidth(t);
  315.     size := ImageSize(0,0,lg,ht);
  316.     GetMem(vptr,size);
  317.     If vptr <> Nil Then GetImage(0,0,lg,ht,vptr^);
  318.     SetViewPort(0,0,lg,ht,True);
  319.     ClearViewPort;
  320.     outtext(t);
  321.     SetViewPort(0,0,xmaxpix,ymaxpix,True);
  322.   End;
  323. End;                                                                { prompt }
  324.  
  325. Function confirmquit(t : string) : boolean;
  326. { asks user if s/he relly wants to quit                                      }
  327.   Var ch : char;
  328. Begin                                                          { confirmquit }
  329.   prompt(t);
  330.   Repeat
  331.     ch := UpCase(ReadKey);
  332.   Until ch In [esc,ctrlc,'Y','N'];
  333.   confirmquit := ch In [esc,ctrlc,'Y'];
  334.   unprompt;
  335. End;                                                           { confirmquit }
  336.  
  337. Function checkuser : boolean;
  338. { check if user rang                                                         }
  339.   Var ch : char;
  340. Begin                                                            { checkuser }
  341.   If KeyPressed Then
  342.   Begin
  343.     ch := UpCase(ReadKey);
  344.     If Not (ch In ['Q',esc,ctrlc]) Then
  345.     Begin
  346.       Repeat Until KeyPressed;
  347.       ch := UpCase(ReadKey);
  348.     End;
  349.     If ch In ['Q',esc,ctrlc] Then
  350.              checkuser := confirmquit('Do you really want to quit?');
  351.   End Else checkuser := False;
  352. End;                                                             { checkuser }
  353.  
  354. Procedure showmsg(t : string);
  355. { show message in prompt line; wait for key to be hit                        }
  356.   Var ch : char;
  357. Begin                                                              { showmsg }
  358.   prompt(t);
  359.   ch := ReadKey;
  360. End;                                                               { showmsg }
  361.  
  362. Procedure errmsg(t : string);
  363. { display an error message                                                   }
  364. Begin                                                               { errmsg }
  365.   Sound(440);
  366.   Delay(200);
  367.   NoSound;
  368.   showmsg(t);
  369. End;                                                                { errmsg }
  370.  
  371. Procedure showprogress(what : byte);
  372. { if what = 0 : save lower right corner for later restore                    }
  373. {         = 1 : show a sign of progress in upper right corner of screen      }
  374. { otherwise   :  restore original contents                                   }
  375. Begin                                                         { showprogress }
  376.   Case what Of
  377.     0 : Begin
  378.           PutImage(xmaxpix-tw,ymaxpix-th,smilepic^,NormalPut);
  379.           isput := True;
  380.         End;
  381.     1 : Begin
  382.           PutImage(xmaxpix-tw,ymaxpix-th,smilepic^,XOrPut);
  383.           isput := Not isput;
  384.         End;
  385.    Else If isput Then PutImage(xmaxpix-tw,ymaxpix-th,smilepic^,XOrPut);
  386.   End;
  387. End;                                                          { showprogress }
  388.  
  389. Procedure save(Var screenfile:scrfile);
  390. { save screen on disk file - uses same buffer as preservescreen              }
  391.    Var picd : picdesc;
  392.        i : byte;
  393.        axmax, savxmax : integer;
  394. Begin                                                                 { save }
  395.   savxmax := xmaxpix Div nchunk;
  396.   axmax := -1;
  397.   i := 0;
  398.   Repeat
  399.     Inc(i);
  400.     With picd Do
  401.     Begin
  402.       version  := currversion;
  403.       follow   := nchunk - i;
  404.       grdriver := thisgraphdriver;
  405.       grmode   := thisgraphmode;
  406.       xmin     := Succ(axmax);
  407.       ymin     := 0;
  408.       axmax    := xmin + savxmax;
  409.       If axmax > xmaxpix Then axmax := xmaxpix;
  410.       size     := ImageSize(xmin,0,axmax,ymaxpix);
  411.       GetImage(xmin,0,axmax,ymaxpix,psc[1].vptr^);
  412.     End;
  413.     {$I- } BlockWrite(screenfile,picd,SizeOf(picd));
  414.     BlockWrite(screenfile,psc[1].vptr^,picd.size); {$I+ }
  415.   Until axmax >= xmaxpix;
  416.   If IOResult <> 0 Then
  417.   Begin
  418.     prompt('Some I/O error occurred - save may have gone awry!');
  419.     i := Ord(ReadKey);
  420.     unprompt;
  421.   End;
  422. End;                                                                  { save }
  423.  
  424. Procedure scrprint(prno, nrep : byte);
  425. { hardcopy of Hercules screen on STAR NL10 or Epson FX type printers         }
  426. { prno : number of printer port (1..4)                                       }
  427. { nrep : number of times each line is overprinted                            }
  428.  
  429.   Const errormask = $29;
  430.         intpr = $17;
  431.  
  432.   Var i, symaxpix, prmax, portno : word;
  433.       continue : boolean;
  434.       bytebuf : Array [1..2000] Of byte;
  435.       regs : Registers;
  436.  
  437.   Function checkprinter : boolean;
  438.   { check printer status; if not ready, holler at user. Accept 'quit' command }
  439.     Var quitit : boolean;
  440.   Begin                                                       { checkprinter }
  441.     quitit := False;
  442.     With regs Do
  443.     Begin
  444.       Repeat
  445.         ah := 2;
  446.         dx := portno;
  447.         Intr(intpr,regs);
  448.         If (ah And errormask) <> 0 Then
  449.         Begin
  450.           prompt('Please, check the printer!');
  451.           quitit := UpCase(Readkey) In ['Q',ctrlc,esc];
  452.           unprompt;
  453.         End;
  454.       Until ((ah And errormask) = 0) Or quitit;
  455.     End;
  456.     checkprinter := Not quitit;
  457.   End;                                                        { checkprinter }
  458.  
  459.   Procedure printbyte(byt : byte);
  460.   { output a single byte to printer port                                     }
  461.   Begin                                                          { printbyte }
  462.     If continue Then
  463.     Begin
  464.       With regs Do
  465.       Begin
  466.         ah := $00;
  467.         al := byt;
  468.         dx := portno;
  469.         Intr(intpr,regs);
  470.         If (ah And errormask) <> 0 Then continue := checkprinter;
  471.       End;
  472.     End;
  473.   End;                                                           { printbyte }
  474.  
  475.   Procedure prinit;
  476.   { initialize printer and set to proper linefeed                            }
  477.   Begin                                                             { prinit }
  478.     With regs Do
  479.     Begin
  480.       ah := $01;
  481.       dx := portno;
  482.       Intr(intpr,regs);
  483.     End;
  484.     printbyte(27);   { Esc'3'#24 : set linefeed to 24/180 " }
  485.     printbyte(51);
  486.     printbyte(24);
  487.     printbyte(10);   { tighten paper }
  488.   End;                                                              { prinit }
  489.  
  490.   Procedure doline(top, i : integer);
  491.   { prepare a single printer line                                            }
  492.  
  493.     Var rep, j : integer;
  494.  
  495.     Function ConstructByte(j, i : integer) : byte;
  496.     { construct a single byte of a printer line                              }
  497.       Const bits : Array [0..7] Of byte = (128,64,32,16,8,4,2,1);
  498.       Var CByte, k : byte;
  499.     Begin                                                    { constructbyte }
  500.       i := i Shl 3;
  501.       cbyte := 0;
  502.       For k := 0 To top Do
  503.         If GetPixel(j,i+k) <> Black Then cbyte := cbyte Or bits[k];
  504.       constructbyte := cbyte;
  505.     End;                                                     { constructbyte }
  506.  
  507.   Begin                                                             { doline }
  508.     If continue Then
  509.     Begin
  510.       For j := 0 To xmaxpix Do bytebuf[j+6] := constructbyte(j,i);
  511.       {$I- }
  512.       For rep := 1 To nrep Do
  513.       Begin
  514.         For j := 1 To prmax Do printbyte(bytebuf[j]);
  515.         printbyte(13);
  516.       End;
  517.       printbyte(10);
  518.       {$I+ }
  519.     End;
  520.   End;                                                              { doline }
  521.  
  522. Begin                                                             { scrprint }
  523.   If (prno >= 1) And (prno <= 4) Then portno := Pred(prno) Else portno := 0;
  524.   symaxpix := Succ(ymaxpix);
  525.   continue := checkprinter;
  526.   If Not continue Then Exit;
  527.   prinit;
  528.   {$I- }
  529.   i := Succ(xmaxpix);
  530.   bytebuf[1] := 27;       { Esc'*'#6.. : select screen graphics mode }
  531.   bytebuf[2] := 42;
  532.   bytebuf[3] :=  6;
  533.   bytebuf[4] := Lo(i);
  534.   bytebuf[5] := Hi(i);
  535.   prmax := xmaxpix + 6;
  536.   For i := 0 To Pred(symaxpix Shr 3) Do doline(7,i);
  537.   If symaxpix And 7 <> 0 Then doline(symaxpix and 7,symaxpix Shr 3);
  538.   If Not checkprinter Then Exit;
  539.   printbyte(27);          { Esc'2' : reset to normal linefeed }
  540.   printbyte(50);
  541.   {$I+ }
  542.   If IOResult <> 0 Then
  543.   Begin
  544.     prompt('Some I/O error occurred - hardcopy may have gone awry!');
  545.     i := Ord(ReadKey);
  546.     unprompt;
  547.   End;
  548. End;                                                              { scrprint }
  549.  
  550. Function intext(Var t : string; maxlg : byte) : boolean;
  551. {read a line (max length: maxlg) of kbd input in graphics mode               }
  552.   Var c : char;
  553.       arrowkey : boolean;
  554.       curlg, ht, clg, lg, size : word;
  555.       vptri : pointer;
  556. Begin                                                               { intext }
  557.   SetViewPort(0,0,xmaxpix,ymaxpix,True);
  558.   ht := TextHeight('Ap');
  559.   clg := TextWidth('M');
  560.   lg := maxlg * clg;
  561.   size := ImageSize(0,ht,lg,ht+ht);
  562.   GetMem(vptri,size);
  563.   If vptri <> Nil Then GetImage(0,ht,lg,ht+ht,vptri^);
  564.   SetViewPort(0,ht,lg,ht+ht,True);
  565.   ClearViewPort;
  566.   t := '';
  567.   curlg := 0;
  568.   arrowkey := False;
  569.   Repeat
  570.     PutImage(curlg*clg,0,curspic^,NormalPut);
  571.     c := ReadKey;
  572.     PutImage(curlg*clg,0,nilpic^,NormalPut);
  573.     Case c Of
  574.      '!'..'~' : Begin
  575.                   outtextxy(curlg*clg,0,c);
  576.                   t := t + c;
  577.                   Inc(curlg);
  578.                 End;
  579.      bksp : If curlg > 0 Then
  580.             Begin
  581.               PutImage(Pred(curlg)*clg,0,nilpic^,NormalPut);
  582.               delete(t,curlg,1);
  583.               Dec(curlg);
  584.           End;
  585.       #0 : Begin
  586.              c := ReadKey;
  587.              arrowkey := (t = '') And
  588.              (c In [lfarr,rtarr,uparr,dnarr,clfarr,crtarr,cuparr,cdnarr]);
  589.            End;
  590.     End;
  591.   Until (length(t) = maxlg) Or (c In [ctrlc,cr,esc]) Or arrowkey;
  592.   If c In [ctrlc,esc] Then t := '';
  593.   intext := Not arrowkey;
  594.   SetViewPort(0,0,xmaxpix,ymaxpix,True);
  595.   If vptri <> Nil Then PutImage(0,ht,vptri^,NormalPut);
  596.   If vptri <> Nil Then FreeMem(vptri,size);
  597. End;                                                                { intext }
  598.  
  599. Begin                                 { initialization part of unit mapgraph }
  600.   xmaxpix  := 0;
  601.   ymaxpix  := 0;
  602.   aspect   := 0.0;
  603.   nchunk   := 0;
  604.   hlinpic  := Nil;
  605.   vlinpic  := Nil;
  606.   curspic  := Nil;
  607.   nilpic   := Nil;
  608.   smilepic := Nil;
  609. End.                                                              { mapgraph }
  610.